package sxe.core.cs511.team2_2;

import java.awt.image.BufferedImage;
import java.util.Calendar;
import snobject.*;
import step.EvaluationFailure;
import step.FunctionWrapper;
import step.exceptions.ResourceUnavailableException;

/** OVERVIEW:  A class that defines the opcode personcount.  This opcode will take an snImage as an argument
 *  and return an snInteger representing the number of people currently in the room.
 *  This class is a procedural abstraction.  The abstraction function is AF(c) = {a tracker object}.
 *  The representation invariant is that the tracker object must be non-null.
 * @author skelly
 *
 */

public class personcount extends FunctionWrapper {
	private Calendar cal = null;
	private BlobDetector blobDetector = new BlobDetector(1);
	private Tracker tracker = null;
	/** Constructor */
	public personcount(){
		
	}

	/** EFFECTS:  This method takes an snImage as an argument and returns the number of blobs in it.
	 *  REQUIRES:  The first argument to be non-null.
	 * @return an snPair containing the current time, in milliseconds since Jan 1, 1970,
	 * and the number of blobs in the image.
	 * @throws EvaluationFailure
	 */
	public snObject Call(snObjectArgList argv) throws EvaluationFailure,
			ClassCastException, ArrayIndexOutOfBoundsException,
			ResourceUnavailableException {
		
		snImage sni = argv.popImage();
		
		snStruct vect;
		if(tracker==null)
			if(argv.hasNext()){
				vect = argv.popStruct();
				snDouble x = (snDouble) vect.get("x");
				snDouble y = (snDouble) vect.get("y");
				snDouble cutoff = (snDouble) vect.get("dist");
				if((x!=null)&&(y!=null)){	
					double dx = x.getDbl();
					double dy = y.getDbl();
					if(cutoff==null)
						tracker=new Tracker(dx,dy);
					else{
						double ddist = cutoff.getDbl();
						tracker=new Tracker(dx,dy,ddist);
					}
				}
			}
			
		if(tracker==null)
			tracker =  new Tracker(-1,0);
		
		/* do not directly manipulate the original image, instead work with a copy */
		BufferedImage buffImg = sni.getImageCopy(); 
		
		BlobBag bag = blobDetector.detectBlobs(buffImg);
		int count = 0;
		if (bag != null){
			tracker.add(bag);
			count = tracker.computeCount(100);
		}
		
		cal = Calendar.getInstance();
		double thistime = (double)cal.getTimeInMillis();
		return new snPair(new snDouble(thistime), new snInteger(count));
	}

}
